package com.zzq.my.jetpacks.util

import kotlinx.coroutines.*


/* todo ------注释说明 自定义协程的作用域CoroutineScope------ */
fun <T> async(loader: suspend () -> T): Deferred<T> {
//    val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
//        exception.printStackTrace()
//    }
    val deferred = CoroutineScope(Dispatchers.IO).async {
        loader.invoke()
    }
    return deferred
}

fun <T> Deferred<T>.await(
    onSuccess: (T) -> Unit,
    onError: (e: Exception) -> Unit,
    onComplete: (() -> Unit)? = null
) {
    val job = CoroutineScope(Dispatchers.Main).launch {

        try {
            val result = this@await.await()
            onSuccess(result)

        } catch (e: Exception) {
            e.printStackTrace()
            onError(e)
        } finally {
            onComplete?.invoke()
        }
    }
}
/* todo ------注释说明 end  自定义协程的作用域CoroutineScope------ */


/**
 * todo 封装了协程的异常捕获
 * todo viewModelScope.rxLaunch<String> {
onRequest = {
//网络请求
resposity.getData()
}
onSuccess = {
//成功回调
}
onError = {
//失败回调
}
}
}
 */
fun <T> CoroutineScope.rxLaunch(init: CoroutineBuilder<T>.() -> Unit) {
    val result = CoroutineBuilder<T>().apply(init)
    val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
        result.onError?.invoke(exception)
    }
    launch(coroutineExceptionHandler) {
        val res: T? = result.onRequest?.invoke()
        res?.let {
            result.onSuccess?.invoke(it)
        }
    }
}

class CoroutineBuilder<T> {
    var onRequest: (suspend () -> T?)? = null
    var onSuccess: ((T) -> Unit)? = null
    var onError: ((Throwable) -> Unit)? = null
}
/* todo ------封装了协程的异常捕获 end  ----- */